// g++ dtls_tools.cpp dtls_tools_client.cpp -o dtls_tools_client -I ./ -L ./ -lssl -lcrypto -lpthread -ldl

#include "dtls_tools.hpp"


int main() {
  int sock = CreateSocket(CLIENT_PORT);
  /* startup SSL */
  krx_begin();
 
  /* create client objects */
  krx client;
 
  /* init client. */
  if(krx_ssl_ctx_init(&client, "client") < 0) {
    exit(EXIT_FAILURE);
  }
  if(krx_ssl_init(&client, 0, krx_ssl_client_info_callback) < 0) {
    exit(EXIT_FAILURE);
  }
 
  printf("+ Initialized client.\n");

  char replybuf[MAX_PACKAGE_LEN];
  int replylen = 0;

  /* kickoff handshake; initiated by client (e.g. browser) */
  SSL_do_handshake(client.ssl);
  krx_ssl_handle_traffic_read(&client, replybuf, replylen);
 
  char outbuf[MAX_PACKAGE_LEN];
  struct sockaddr_in seraddr;
  socklen_t seraddr_len = sizeof(seraddr);
  bzero(&seraddr,sizeof(seraddr));  
  seraddr.sin_family = AF_INET;  
  seraddr.sin_port = htons(SERVER_PORT);  
  seraddr.sin_addr.s_addr = inet_addr(SERVER_IP);  

  if (replylen)
  {
    int n = sendto(sock, replybuf, replylen, 0, (struct sockaddr*)&seraddr,sizeof(seraddr));
    printf("sendto,n=%d,addr=%s:%u!\n",n,inet_ntoa(seraddr.sin_addr),ntohs(seraddr.sin_port));
  }

  while(true) {
      // recvfrom a client
      int n = recvfrom(sock, (char *)&outbuf, MAX_PACKAGE_LEN, 0, (struct sockaddr *)&seraddr, &seraddr_len);
      if (n < 0) {
          perror("Unable to recvfrom");
          exit(EXIT_FAILURE);
      }
      printf("recvfrom ok,n=%d,addr=%s:%u!\n",n,inet_ntoa(seraddr.sin_addr),ntohs(seraddr.sin_port));
      //print_dump((unsigned char*)outbuf, n);

      replylen = 0;
      if (ProcessOnDtls(outbuf, n, &client, replybuf, replylen))
      {
        printf("ProcessOnDtls error\n");
        break;
      }
      printf("ProcessOnDtls ok! replylen=%d\n", replylen);
      //print_dump((unsigned char*)replybuf, replylen);
      if (replylen)
      {
        int n = sendto(sock, replybuf, replylen, 0, (struct sockaddr*)&seraddr,sizeof(seraddr));
        printf("sendto,n=%d,addr=%s:%u!\n",n,inet_ntoa(seraddr.sin_addr),ntohs(seraddr.sin_port));
      }
  }

  krx_ssl_shutdown(&client);
 
  krx_end();
  close(sock);
  return EXIT_SUCCESS;
}
 